package blocks {
	import entities.Player;
	
	import flash.display.BitmapData;
	
	import org.flixel.FlxG;
	import org.flixel.FlxPoint;
	import org.flixel.FlxSound;
	import org.flixel.FlxSprite;
	
	import tools.Fx;
	import tools.MyFlxSprite;
	
	
	public class DynamicBlock extends FlxSprite {
		protected var tileID:uint;
		protected var sound:FlxSound;
		protected var tileInfos:Object
		protected var infos:Object;
		
		public var name:String;
		public var type:String;
		
		// used for bloc activated by a trigger (doors, fallingTraps)
		public var _triggerName:String;
		
		/** 
		 * The main contructor, 
		 * 
		 * @param	X
		 * @param 	Y
		 * @param 	infos
		 * @param 	mapName
		 * 
		 * @return nothing
		 **/
		
		public function DynamicBlock(X:int, Y:int, infos:Object=null, mapName:String=null):void {
			super(X, Y);
			
			
			//used for position size and moves
			tileInfos = mapName ? Registry.tileInfos[mapName] : infos.tileInfos;
			
			// if tileSize is not manually defined, it will fill automatically with tileSheet size
			width = tileInfos.tileSize ? tileInfos.tileSize[0] : tileInfos.tileSheet.width;
			height = tileInfos.tileSize ? tileInfos.tileSize[1] : tileInfos.tileSheet.height;
			
			
			// chose the correct group to put in
			this.infos = infos;
			type = infos.type;
			name = infos.name;
			
			
			switch(type){
				case 'trigger':
				case 'collect':
				case 'checkpoint':
					Registry.dynamicPool.add(this);
					break;
				
				default :
					Registry.solidTilesPool.add(this);
			}
			
			
			solid = true;
			if (!infos.collide){
				solid = false;
			}
			
			
			active = false;
			immovable = true;
			tileID = infos.firstTileID ? infos.firstTileID : infos.tileID;
			
			if (infos.soundUrl) {
				sound = FlxG.stream(infos.soundUrl, 1,false,false);
				sound.stop();
			}
			
			drawTile(tileInfos.tileSheet, width, height, tileID);
		}
		
		protected var sprite:FlxSprite;
		
		
		/**
		 * This function is the one who clean, draw and display the content of the Tile
		 *
		 *  @param	TileGraphic	the full tileSheet Bitmapdata
		 *  @param	TileWidth	width of one tile
		 *  @param	TileHeight	height of one tile
		 *  @param	tileID		the index of the tile in the tileSheet
		 *  @param	X			The initial X position of the content (useful for collision detection)
		 *  @param	Y			The initial Y position of the content (useful for collision detection)
		 *
		 *  @return	the FlxSprite of the drawn tile
		 *
		 **/
		
		protected function drawTile(TileGraphic:BitmapData, TileWidth:uint=0, TileHeight:uint=0, tileID:uint=0, X:uint=0, Y:uint=0):FlxSprite {
			
			//First create a tile brush
			sprite = new MyFlxSprite().loadGraphicWithBitmap(TileGraphic, true, false, TileWidth, TileHeight);
			sprite.frameHeight = TileWidth;
			sprite.frameWidth = TileHeight;
			makeGraphic(width, height, FlxG.BLACK)
			sprite.frame = tileID;
			
			var spriteWidth:uint = sprite.width;
			var spriteHeight:uint = sprite.height;
			var total:uint = sprite.frames;
			
			// Then clean the sprite
			var regen:Boolean = false;
			if (width % sprite.width != 0) {
				width = uint(width / spriteWidth + 1) * spriteWidth;
				regen = true;
			}
			if (height % sprite.height != 0) {
				height = uint(height / spriteHeight + 1) * spriteHeight;
				regen = true;
			}
			if (regen)
				makeGraphic(width, height, 0, true);
			else
				this.fill(0);
			
			sprite.origin = new FlxPoint(50, 50);
			
			stamp(sprite, X, Y);
			
			return this;
		}
		
		
		/**
		 * This function switch the tile between tileID and newTileID, you must define a newTileID in the config.xml file First, else it will be replaced by the tile n°0
		 *
		 *  @param	switchCollision	if the function have to allow collision
		 *
		 *  @return	the new tileID
		 *
		 **/
		
		public function switchTile(switchCollision:Boolean=true):uint {
			var firstTileID:uint = infos.firstTileID ? infos.firstTileID :  infos.tileID;
			var switchTo:uint = (tileID == firstTileID) ? (infos.newTileID) ? infos.newTileID : 0 : firstTileID;
			
			tileID = switchTo;
			if (sound) sound.play();
			
			drawTile(tileInfos.tileSheet, width, height, switchTo);
			
			if (switchCollision)
				solid = !solid;
			
			active=false;
			
			return switchTo;
		}
		
		/**
		 * This function remove the tile From Board and play a sound and increase score if they are defined
		 *
		 *  @return	nothing
		 *
		 **/
		override public function kill():void {
			if (sound)	sound.play();
			if (infos.points) Registry.player.score += infos.points;
			super.kill();
		}
		
		
		/**
		 * Simply call the destroy funtion but add visual effect (particles and shake screen)
		 *
		 *  @return	nothing
		 *
		 **/
		public function explodeBlock():void {
			Registry.fx.particles(this);
			Registry.fx.shake();
			kill();
			return;
		}
		
		
		public function activate():void{
			active = true;
			if(sound) sound.play();
		}
	}
}
